package com.lizi.apidoc.utils;

import com.lizi.apidoc.constants.AnnotationKeyName;
import com.lizi.apidoc.constants.DocGlobal;
import com.thoughtworks.qdox.model.DocletTag;
import com.thoughtworks.qdox.model.JavaAnnotation;
import com.thoughtworks.qdox.model.JavaField;
import com.thoughtworks.qdox.model.JavaMethod;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * DocUtil
 * @author 张健文【zhangjw@3vjia.com】
 * @since 2020/4/1 17:15
 * @modified by:
 */
public class DocUtil {

    /**
     * 是否是合法的java类名称
     *
     * @param className class nem
     * @return boolean
     */
    public static boolean isClassName(String className) {
        if (StringUtil.isNullOrEmpty(className)) {
            return false;
        }
        if (className.contains("<") && !className.contains(">")) {
            return false;
        } else if (className.contains(">") && !className.contains("<")) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * handle spring mvc mapping value
     *
     * @param annotation JavaAnnotation
     * @return String
     */
    public static String getRequestMappingValue(JavaAnnotation annotation) {
        Object value = annotation.getNamedParameter(AnnotationKeyName.VALUE);
        if (null == value) {
            return "/";
        } else {
            return value.toString();
        }
    }

    /**
     * handle spring mvc method
     *
     * @param methodName method name
     * @return String
     */
    public static String getHttpMethod(String methodName) {
        switch (methodName) {
            case "RequestMethod.POST":
                return "POST";
            case "RequestMethod.GET":
                return "GET";
            case "RequestMethod.PUT":
                return "PUT";
            case "RequestMethod.DELETE":
                return "DELETE";
            default:
                return "GET";
        }
    }

    /**
     * 得到mvc的链接地址，全地址
     * @param baseServer
     * @param controllerUrl
     * @param urls
     * @return
     */
    public static String getMvcUrls(String baseServer, String controllerUrl, List<String> urls) {
        StringBuilder sb = new StringBuilder();
        int size = urls.size();
        String tmpBaseServer = StringUtil.trim(baseServer,"/");
        String tmpControllerUrl = StringUtil.trim(controllerUrl,"/");

        //改为取第一个
        for(String url : urls){
            String mvcUrl = String.format("%s/%s/%s",tmpBaseServer,tmpControllerUrl,StringUtil.trim(url,"/"));
            sb.append(mvcUrl);
            break;
        }

//        for(String url : urls){
//            String mvcUrl = String.format("%s/%s/%s",tmpBaseServer,tmpControllerUrl,StringUtil.trim(url,"/"));
//            sb.append(mvcUrl+";\t");
//        }
        return sb.toString();
    }

    /**
     * obtain params comments
     *
     * @param javaMethod JavaMethod
     * @param tagName    java comments tag
     * @param className  class name
     * @return Map
     */
    public static Map<String, String> getParamsComments(final JavaMethod javaMethod, final String tagName, final String className) {
        List<DocletTag> paramTags = javaMethod.getTagsByName(tagName);
        Map<String, String> paramTagMap = new HashMap<>();
        for (DocletTag docletTag : paramTags) {
            String value = docletTag.getValue();
            if (StringUtil.isNullOrEmpty(value)) {
                throw new RuntimeException("ERROR: #" + javaMethod.getName()
                        + "() - bad @" + tagName + " javadoc from " + javaMethod.getDeclaringClass().getCanonicalName() + ", must be add comment if you use it.");
            }
            String pName;
            String pValue;
            int idx = value.indexOf("\n");
            //existed \n
            if (idx > -1) {
                pName = value.substring(0, idx);
                pValue = value.substring(idx + 1);
            } else {
                pName = (value.indexOf(" ") > -1) ? value.substring(0, value.indexOf(" ")) : value;
                pValue = value.indexOf(" ") > -1 ? value.substring(value.indexOf(' ') + 1) : DocGlobal.NO_COMMENTS_FOUND;
            }
            paramTagMap.put(pName, pValue);
        }
        return paramTagMap;
    }

    /**
     * Get field tags
     *
     * @param field JavaField
     * @return map
     */
    public static Map<String, String> getFieldTagsValue(final JavaField field) {
        List<DocletTag> paramTags = field.getTags();
        return paramTags.stream().collect(Collectors.toMap(DocletTag::getName, DocletTag::getValue));
    }

    /**
     * match controller package
     *
     * @param packageFilters package filter
     * @param controllerName controller name
     * @return boolean
     */
    public static boolean isMatch(String packageFilters, String controllerName) {
        if (!StringUtil.isNullOrEmpty(packageFilters)) {
            String[] patterns = packageFilters.split(",");
            for (String str : patterns) {
                if (str.endsWith("*")) {
                    String name = str.substring(0, str.length() - 2);
                    if (controllerName.contains(name)) {
                        return true;
                    }
                } else {
                    if (controllerName.contains(str)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
}
